﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKArchMethodLibrary.Utils;
using YJKElementFinish.ColumnSurface.DataDefinition;
using YJKElementFinish.ColumnSurface.Managers;
using YJKElementFinish.MultiWallEdit.DataDefinition;
using YJKElementFinish.MultiWallEdit.Forms;

namespace YJKElementFinish.MultiWallEdit.Controller
{
	public class WallEditController
	{
		public WallEditController(ExternalCommandData cmdData)
		{
			this.m_ComdData = cmdData;
			this.m_UIApp = cmdData.Application;
			this.m_UIDoc = this.m_UIApp.ActiveUIDocument;
			this.m_App = this.m_UIApp.Application;
			this.m_Doc = this.m_UIDoc.Document;
		}

		public Result Edit()
		{
			List<Wall> selWalls = new List<Wall>();
			if (!WallCommon.SelectWalls(this.m_UIDoc, ref selWalls))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			WallGroupingController wallGroupingController = new WallGroupingController(this.m_ComdData);
			List<List<Wall>> list = new List<List<Wall>>();
			List<List<Wall>> list2 = new List<List<Wall>>();
			List<Wall> list3 = new List<Wall>();
			wallGroupingController.WallGrouping(selWalls, ref list, ref list2, ref list3);
			List<List<Wall>> list4 = new List<List<Wall>>();
			list4.AddRange(list);
			list4.AddRange(list2);
			List<List<WallType>> list5 = new List<List<WallType>>();
			List<KeyValuePair<int, bool>> list6 = new List<KeyValuePair<int, bool>>();
			wallGroupingController.GetWallTypeGroup(list4, ref list5, ref list6);
			if (list5.Count == 0)
			{
				RevitVersionFuncs.ClearSelection(this.m_UIDoc.Selection);
				MessageBox.Show("无可编辑的成组多墙", "盈建科提示");
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			WallTypeEditForm wallTypeEditForm = new WallTypeEditForm(list5, this.m_Doc);
			if (wallTypeEditForm.ShowDialog() != DialogResult.OK)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			List<WallTypeGroupInfos> combinationInfosByGroup = wallTypeEditForm.GetCombinationInfosByGroup();
			List<WallTypeGroupInfos> list7 = new List<WallTypeGroupInfos>();
			int i;
			for (i = 0; i < list.Count; i++)
			{
				list7.Add(combinationInfosByGroup[list6[i].Key]);
			}
			List<WallTypeGroupInfos> list8 = new List<WallTypeGroupInfos>();
			while (i < list.Count + list2.Count)
			{
				list8.Add(combinationInfosByGroup[list6[i].Key]);
				i++;
			}
			this.EditLinearWall(list, list7);
			this.EditArcWall(list2, list8);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void EditLinearWall(List<List<Wall>> linearWalls, List<WallTypeGroupInfos> combinationInfosByGroup)
		{
			for (int i = 0; i < linearWalls.Count; i++)
			{
				List<Wall> walls = linearWalls[i];
				WallTypeGroupInfos wallTypeGroupInfos = combinationInfosByGroup[i];
				List<WallTypeLayerInfos> layerTypeList = wallTypeGroupInfos.LayerTypeList;
				this.EditSingleGroupWall(walls, layerTypeList);
			}
		}

		private bool EditSingleGroupWall(List<Wall> walls, List<WallTypeLayerInfos> combinationWallTypes)
		{
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.m_Doc);
				transaction.Start("edit wall");
				int num = -1;
				Wall wall = WallCommon.FindMainWall(walls, this.m_Doc, ref num);
				if (num == -1)
				{
					transaction.RollBack();
					return false;
				}
				List<double> list = new List<double>();
				for (int i = 0; i < walls.Count; i++)
				{
					list.Add(walls[i].WallType.Width);
				}
				List<double> list2 = new List<double>();
				for (int i = 0; i < walls.Count; i++)
				{
					WallTypeLayerInfos wallTypeLayerInfos = combinationWallTypes[i];
					if (wallTypeLayerInfos == null)
					{
						list2.Add(0.0);
					}
					else
					{
						WallType wallType = WallTypeManager.GetWallType(wallTypeLayerInfos.TypeName, wall.WallType, wallTypeLayerInfos.StructureLayerList(), this.m_Doc, false);
						if (wallType != null)
						{
							list2.Add(wallType.Width);
						}
						else
						{
							list2.Add(0.0);
						}
					}
				}
				this.ChangeTypeAndMoveWallGroup(walls, combinationWallTypes, num, list, list2);
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null)
				{
					transaction.RollBack();
				}
				return false;
			}
			return true;
		}

		private void ChangeTypeAndMoveWallGroup(List<Wall> walls, List<WallTypeLayerInfos> combinationWallTypes, int refWallIndex, List<double> oldWidthList, List<double> newWidthList)
		{
			Wall wall = walls[refWallIndex];
			List<ElementId> list = new List<ElementId>();
			for (int i = 0; i < walls.Count; i++)
			{
				WallTypeLayerInfos wallTypeLayerInfos = combinationWallTypes[i];
				if (wallTypeLayerInfos == null)
				{
					list.Add(walls[i].Id);
				}
				else
				{
					WallType wallType = WallTypeManager.GetWallType(wallTypeLayerInfos.TypeName, wall.WallType, wallTypeLayerInfos.StructureLayerList(), this.m_Doc, false);
					if (wallType != null)
					{
						Curve curve = (walls[i].Location as LocationCurve).Curve;
						walls[i].WallType = wallType;
						double offset = this.GetOffset(i, refWallIndex, oldWidthList, newWidthList);
						if (!Geometry.IsEqual(offset, 0.0) || i == refWallIndex)
						{
							Wall wall2 = walls[i];
							Curve curve2 = (wall2.Location as LocationCurve).Curve;
							XYZ orientation = wall2.Orientation;
							if (i == refWallIndex)
							{
								WallCommon.SetKeyRefParam(walls[i]);
								(wall2.Location as LocationCurve).Curve = curve;
							}
							else
							{
								(wall2.Location as LocationCurve).Curve = WallCommon.GetOffsetWallLocation(curve2, orientation, offset);
							}
						}
					}
				}
			}
			this.m_Doc.Delete(list);
		}

		private double GetOffset(int currentIndex, int kernelIndex, List<double> oldWidthList, List<double> newWidthList)
		{
			double num = oldWidthList[currentIndex] / 2.0 + oldWidthList[kernelIndex] / 2.0;
			double num2 = newWidthList[currentIndex] / 2.0 + newWidthList[kernelIndex] / 2.0;
			if (currentIndex < kernelIndex)
			{
				for (int i = currentIndex + 1; i < kernelIndex; i++)
				{
					num += oldWidthList[i];
					num2 += newWidthList[i];
				}
				return num - num2;
			}
			if (currentIndex > kernelIndex)
			{
				for (int j = kernelIndex + 1; j < currentIndex; j++)
				{
					num += oldWidthList[j];
					num2 += newWidthList[j];
				}
				return num2 - num;
			}
			return 0.0;
		}

		private void EditArcWall(List<List<Wall>> arcWalls, List<WallTypeGroupInfos> combinationInfosByGroup)
		{
			for (int i = 0; i < arcWalls.Count; i++)
			{
				List<Wall> walls = arcWalls[i];
				WallTypeGroupInfos wallTypeGroupInfos = combinationInfosByGroup[i];
				List<WallTypeLayerInfos> layerTypeList = wallTypeGroupInfos.LayerTypeList;
				this.EditSingleGroupWall(walls, layerTypeList);
			}
		}

		private ExternalCommandData m_ComdData;

		private UIApplication m_UIApp;

		private UIDocument m_UIDoc;

		private Autodesk.Revit.ApplicationServices.Application m_App;

		private Document m_Doc;
	}
}
